<?php
// Created by bheesham
class gcThumbnails
{
	// Video File
	public $vf = null;
	
	// Video Info
	public $vi = array();
	
	// Prefix of all the image files generated
	public $prefix;
	
	// Image Queue
	public $image_queue = array();
	
	// An array of thumbnails
	public $images = array();	
	
	// The thumbnail images combined
	public $thumbs;
	
	// The information image
	public $info;
	
	// The finished image
	public $fin_image;
	
	// Information for the end image
	public $total_x = 0;
	public $total_y = 0;
	public $cols = 1;
	
	// Working directory
	public $w_dir = 'screenshots/';
	
	// Error trapping
	public $error = null;
	
	// $vf 		= Path to video file
	// $as 		= amount of screen shots
	// $cols 	= the amount of columns you want to be displayed
	function __construct($vf, $as = 9, $cols = 1)
	{
		
		$this->cols = $cols;
		
		if (!file_exists($vf))
		{
			$this->error = 'That video file does NOT exist.';
			return(false);
		}
		
		// Generating the prefix is the utmost important.
		$this->prefix = 'th_bheesham_' . md5_file($vf) . '_';
		
		// Get the duration of the video
		ob_start();
		passthru('ffmpeg -i "' . $vf . '" 2>&1', $retval);
		$info = ob_get_contents();
		ob_end_clean();
		
		// Duration
		$duration = preg_match('/Duration: (.*?),/', $info, $matches, PREG_OFFSET_CAPTURE, 3);
		$duration = $matches[1][0];
		$this->vi[] = 'Duration: ' . $matches[1][0];
		// Video Info
		$vid_info = preg_match('/Video: (.*)/', $info, $matches, PREG_OFFSET_CAPTURE, 3);
		$this->vi[] = $matches[0][0];
		// Audio Info
		$aud_info = preg_match('/Audio: (.*)/', $info, $matches, PREG_OFFSET_CAPTURE, 3);
		$this->vi[] = $matches[0][0];
		
		// Convert Duration to Seconds
		$duration = explode(':', $duration);
		$seconds = $duration[2] + $duration[1]*60 + $duration[0]*60*60;
		$seconds = floor($seconds);
		$equal_divisions = floor($seconds / $as);
		
		for ($i=1;$i<=$as;$i++)
		{
			if (!file_exists($this->w_dir . $this->prefix . $i . '.jpg'))
			{
				// Make equal divisions
				$where = $equal_divisions * $i;
				// Execute FFMPEG to generate the image
				$command = 'ffmpeg -i "'. $vf .'" -r 1 -ss 00:00:' . $where . ' -f mjpeg -t 1 -sameq -s 360*240 "' . $this->w_dir . $this->prefix . $i . '.jpg"';
				$last_line = system($command, $retval);
				if ($retval == 1)
				{
					$this->error = 'An error has occured.';
					return(false);
				}
				$this->add_images($this->prefix . $i . '.jpg');
			}
			else
			{
				$this->error = 'Screenshots have already been generated for this video.';
				return(false);
			}
		}
		
		// Calculate the size of the 
		// thumbnails when all together
		$this->calculate_thumbs();
		
		// Generate the required images
		$this->info_image();
		$this->merge_thumbs();
		
		// Delete the thumbnails
		$this->clean_thumbs();
		
		$info_x = imagesx($this->info);
		$info_y = imagesy($this->info);
		
		// See which image is longer (x-axis) and
		// create a new image according to that
		if ($info_x > $this->total_x)
		{
			$this->fin_image = imagecreatetruecolor($info_x, $this->total_y+$info_y);
		}
		else
		{
			$this->fin_image = imagecreatetruecolor($this->total_x, $this->total_y+$info_y);
		}
		
		// Generate the new image and then display it
		imagecopy($this->fin_image, $this->info, 0, 0, 0, 0, $info_x, $info_y);
		imagecopy($this->fin_image, $this->thumbs, 0, $info_y, 0, 0, $this->total_x, $this->total_y);
		return(true);
	}
	
	// Adds the thumbnails into the queue
	function add_images($array = array())
	{
		if (!is_array($array))
		{
			$array = array($array);
		}
		// Check for existance.
		foreach($array as $file)
		{
			if (!file_exists($this->w_dir . $file))
			{
				$this->error = $this->w_dir . $file . ' does not exist.';
				return(false);
			}
		}
		$this->image_queue = array_merge($this->image_queue, $array);
		return(true);
	}
	
	// Generates the image with the video information on it
	function info_image()
	{
		$font = 'arial.ttf';
		$fontsize = 10;
		$info = implode("\n", $this->vi);
		$info = wordwrap($info);
		$dims = imagettfbbox($fontsize, 0, $font, $info);
		$width = $dims[4] - $dims[6];
		$height = $dims[3] - $dims[5];
		$image = imagecreatetruecolor($width+20, $height+20);
		$bgcolor = imagecolorallocate($image, 0, 0, 0);
		$fontcolor = imagecolorallocate($image, 255, 255, 255);
		imagefilledrectangle($image, 0, 0, $width, $height, $bgcolor);
		$x = 10; 
		$y = $fontsize+10;
		imagettftext($image, $fontsize, 0, $x, $y, $fontcolor, $font, $info);
		$this->info = $image;
		return(true);
	}
	
	// Do some calculations for the thumbnails
	function calculate_thumbs()
	{
		foreach($this->image_queue as $id => $image)
		{
			$this->images[$id] 		= array();
			$this->images[$id]['l'] = $this->w_dir . $image;
			$attrs 					= getimagesize($this->w_dir.$image);
			$this->images[$id]['w'] = $attrs[0];
			$this->images[$id]['h'] = $attrs[1];
			$this->images[$id]['r'] = imagecreatefromjpeg($this->w_dir.$image);
		}
		
		if (isset($error))
		{
			$this->error = $error;
			return(false);
		}
		
		if ($this->cols > 1)
		{
			$this->total_x = $this->images[0]['w'] * $this->cols;
		}
		else
		{
			$this->total_x = $this->images[0]['w'];
		}
		
		$total_y = 0;
		$total_images = count($this->images)-1;
		for($id=0;$id<=$total_images;$id++)
		{
			if ($this->cols > 1 && isset($this->images[$id-1]['h']) && $id > 0)
			{
				$image_pos++;
				if ($image_pos > $this->cols)
				{
					$image_pos = 1;
				}
			}
			else
			{
				$image_pos = 1;
			}
			
			if ($image_pos == 1)
			{
				$total_y = $total_y + $this->images[$id]['h'];
			}
		}
		$this->total_y = $total_y;
		return(true);
	}
	
	// Merge the thumbnails
	function merge_thumbs()
	{
		$this->thumbs = imagecreatetruecolor($this->total_x, $this->total_y);
		$total_images = count($this->images)-1;
		$start_y = 0;
		$start_x = 0;
		$image_pos = 1;
		for($id=0;$id<=$total_images;$id++)
		{
			if ($this->cols > 1 && isset($this->images[$id-1]['w']) && $id > 0)
			{
				$image_pos++;
				if ($image_pos > $this->cols)
				{
					$image_pos = 1;
				}
			}
			else
			{
				$image_pos = 1;
			}
			$start_x = 0;
			for($x=$image_pos-1;$x>=0;$x--)
			{
				if ($x > 0)
				{
					$start_x = $start_x + $this->images[$id-$x]['w'];
				}
			}
			if (isset($this->images[$id]['h']) && $id > 0 && $image_pos == 1)
			{
				$start_y = $start_y + $this->images[$id]['h'];
			}
			imagecopy($this->thumbs, $this->images[$id]['r'], $start_x, $start_y, 0, 0, $this->images[$id]['w'], $this->images[$id]['h']);
		}
		return(true);
	}
	
	// Delete the thumbnail files generated by FFMPEG
	function clean_thumbs()
	{
		foreach($this->image_queue as $image)
		{
			unlink($this->w_dir . $image);
		}
		return(true);
	}
	
	// Display an image resource
	function display($res, $ext)
	{
		switch(strtolower($ext)){
			case ('jpg' || 'jpeg'):
				header('Content-Type: image/jpeg');
				imagejpeg($res);
			break;
			case 'gif':
				header('Content-Type: image/gif');
				imagegif($res);
			break;
			case 'png':
				header('Content-Type: image/png');
				imagepng($res);
			break;
		}
		imagedestroy($res);
		return(true);
	}
	
}
?>